//! Nacos客户端API文档和使用示例
//!
//! 本示例展示了nacos-client的所有主要功能和API使用方法
//! 包括服务注册、发现、配置管理、健康检查等

use std::collections::HashMap;
use nacos_client::{ClientConfigBuilder, ClientInfo, VERSION};
use nacos_client::prelude::*;
use std::time::Duration;

/// 主函数 - 演示完整的API使用流程
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
    // 初始化日志
    tracing_subscriber::fmt::init();

    println!("🚀 Nacos客户端API文档和示例");
    println!("================================\n");

    // 1. 创建客户端配置
    demonstrate_client_config().await?;

    // 2. 创建Nacos客户端
    let client = create_and_test_client().await?;

    // 3. 服务注册与发现
    demonstrate_naming_service(&client).await?;

    // 4. 配置管理
    demonstrate_config_management(&client).await?;

    // 5. 健康检查
    demonstrate_health_check(&client).await?;

    // 6. 缓存管理
    demonstrate_cache_usage(&client).await?;

    // 7. 错误处理
    demonstrate_error_handling().await?;

    println!("\n✅ 所有示例执行完成！");
    Ok(())
}

/// 演示客户端配置的多种创建方式
async fn demonstrate_client_config() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
    println!("📋 1. 客户端配置示例");
    println!("------------------");

    // 方式1: 基础配置
    let basic_config = ClientConfig::new("127.0.0.1:8848");
    println!("基础配置: {:?}", basic_config.server_addr);

    // 方式2: 使用构建器模式
    let builder_config = ClientConfigBuilder::new("localhost:8848")
        .namespace("dev")
        .connect_timeout(5000)
        .read_timeout(10000)
        .max_retries(5)
        .retry_interval(2000)
        .enable_tls(true)
        .auth("admin", "password123")
        .metadata("app", "demo")
        .metadata("version", "1.0.0")
        .build();
    println!("构建器配置: {:?}", builder_config);

    // 方式3: 配置验证
    if let Err(e) = basic_config.validate() {
        println!("配置验证失败: {}", e);
    } else {
        println!("配置验证通过 ✓");
    }

    println!();
    Ok(())
}

/// 创建并测试Nacos客户端
async fn create_and_test_client() -> Result<NacosClient, Box<dyn std::error::Error + Send + Sync>> {
    println!("🔧 2. 创建Nacos客户端");
    println!("------------------");

    let config = ClientConfig::new("127.0.0.1:8848");
    
    // 创建客户端
    let client = NacosClient::new(config).await?;
    println!("客户端创建成功 ✓");

    // 获取客户端信息
    println!("客户端版本: {}", VERSION);
    println!("客户端信息: {:?}", ClientInfo::new());

    println!();
    Ok(client)
}

/// 演示命名服务的使用
async fn demonstrate_naming_service(client: &NacosClient) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
    println!("🏷️ 3. 命名服务示例");
    println!("----------------");

    // 创建命名客户端
    let naming_client = client.naming_client();
    println!("命名客户端创建成功，命名空间: {}", naming_client.namespace());

    // 创建服务实例
    let mut instance = ServiceInstance::new(
        "user-service".to_string(),
        "DEFAULT_GROUP".to_string(),
        "192.168.1.100".to_string(),
        8080,
    );
    instance.weight = 2.0;
    instance.metadata = HashMap::from([
        ("version".to_string(), "1.0.0".to_string()),
        ("env".to_string(), "production".to_string()),
    ]);

    println!("创建服务实例: {:?}", instance);

    // 注册服务
    match naming_client.register_instance("user-service", instance.clone()).await {
        Ok(_) => println!("服务注册成功 ✓"),
        Err(e) => println!("服务注册失败: {}", e),
    }

    // 获取服务实例
    match naming_client.get_instances("user-service", true).await {
        Ok(instances) => {
            println!("发现 {} 个服务实例:", instances.len());
            for (i, inst) in instances.iter().enumerate() {
                println!("  {}. {}:{}", i + 1, inst.ip, inst.port);
            }
        }
        Err(e) => println!("获取服务实例失败: {}", e),
    }

    // 使用缓存获取
    match naming_client.get_instances_cached("user-service", true).await {
        Ok(instances) => println!("缓存获取: {} 个实例", instances.len()),
        Err(e) => println!("缓存获取失败: {}", e),
    }

    // 检查服务是否存在
    match naming_client.service_exists("user-service").await {
        Ok(exists) => println!("服务是否存在: {}", exists),
        Err(e) => println!("检查服务存在失败: {}", e),
    }

    // 获取健康实例
    match naming_client.get_healthy_instances("user-service").await {
        Ok(instances) => println!("健康实例数量: {}", instances.len()),
        Err(e) => println!("获取健康实例失败: {}", e),
    }

    // 注销服务
    match naming_client.deregister_instance("user-service", "192.168.1.100", 8080).await {
        Ok(_) => println!("服务注销成功 ✓"),
        Err(e) => println!("服务注销失败: {}", e),
    }

    println!();
    Ok(())
}

/// 演示配置管理功能
async fn demonstrate_config_management(client: &NacosClient) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
    println!("⚙️ 4. 配置管理示例");
    println!("------------------");

    // 创建配置客户端
    let config_client = client.config_client();

    // 发布配置
    let config_content = r#"{
        "database": {
            "host": "localhost",
            "port": 3306,
            "username": "root",
            "password": "password"
        },
        "redis": {
            "host": "localhost",
            "port": 6379
        }
    }"#;

    match config_client.publish_config("app-config".to_string(), "DEFAULT_GROUP".to_string(), "dev".to_string(), config_content.to_string()).await {
        Ok(success) if success => println!("配置发布成功 ✓"),
        Ok(_) => println!("配置发布失败"),
        Err(e) => println!("配置发布错误: {}", e),
    }

    // 获取配置
    match config_client.get_config("app-config".to_string(), "DEFAULT_GROUP".to_string(), "dev".to_string()).await {
        Ok(content) => {
            println!("获取配置成功:");
            println!("配置内容: {:?}", content);
        }
        Err(e) => println!("获取配置失败: {}", e),
    }

    // 列出配置
    match client.list_configs("dev", "DEFAULT_GROUP", 1, 10).await {
        Ok(configs) => {
            println!("配置列表:");
            for config in configs {
                println!("  - {}", config);
            }
        }
        Err(e) => println!("获取配置列表失败: {}", e),
    }

    // 移除配置
    match client.remove_config("dev", "DEFAULT_GROUP", "app-config").await {
        Ok(success) if success => println!("配置移除成功 ✓"),
        Ok(_) => println!("配置移除失败"),
        Err(e) => println!("配置移除错误: {}", e),
    }

    println!();
    Ok(())
}

/// 演示健康检查功能
async fn demonstrate_health_check(client: &NacosClient) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
    println!("🏥 5. 健康检查示例");
    println!("------------------");

    // 检查单个服务器
    match client.health_check().await {
        Ok(healthy) => println!("服务器健康状态: {}", if healthy { "健康" } else { "不健康" }),
        Err(e) => println!("健康检查失败: {}", e),
    }

    println!();
    Ok(())
}

/// 演示缓存管理功能
async fn demonstrate_cache_usage(client: &NacosClient) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
    println!("💾 6. 缓存管理示例");
    println!("------------------");

    // 创建缓存管理器
    use nacos_client::cache::{CacheManager, LruCache};
    
    let cache_manager = CacheManager::new(
        100,  // 服务实例缓存容量
        100,  // 配置数据缓存容量
        50,   // 服务列表缓存容量
        Duration::from_secs(300), // 5分钟过期
    );

    // 缓存服务实例
    let instance = ServiceInstance::new(
        "cache-service".to_string(),
        "DEFAULT_GROUP".to_string(),
        "192.168.1.101".to_string(),
        8081,
    );

    cache_manager
        .service_instances
        .set("cache-service", vec![instance.clone()])
        .await;

    // 从缓存获取
    if let Some(instances) = cache_manager.service_instances.get("cache-service").await {
        println!("缓存命中: {} 个实例", instances.len());
    }

    // 缓存统计
    let stats = cache_manager.all_stats().await;
    for (cache_name, stats) in stats {
        println!("缓存 {}: {}", cache_name, stats);
    }

    // 清理过期缓存
    let cleaned = cache_manager.cleanup_all().await;
    println!("清理了 {} 个过期缓存条目", cleaned);

    println!();
    Ok(())
}

/// 演示错误处理
async fn demonstrate_error_handling() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
    println!("❗ 7. 错误处理示例");
    println!("------------------");

    // 创建无效配置
    let invalid_config = ClientConfig::new(""); // 空地址
    
    match invalid_config.validate() {
        Ok(_) => println!("配置验证通过"),
        Err(e) => println!("配置验证失败: {}", e),
    }

    // 测试连接错误
    let invalid_config = ClientConfig::new("invalid.host:9999");
    match NacosClient::new(invalid_config).await {
        Ok(_) => println!("连接成功"),
        Err(e) => println!("连接失败: {}", e),
    }

    println!();
    Ok(())
}

/// 服务监听器示例
#[derive(Debug)]
struct LoggingServiceListener;

#[async_trait::async_trait]
impl nacos_client::naming::ServiceListener for LoggingServiceListener {
    async fn on_service_changed(&self, service_name: &str, instances: &[ServiceInstance]) {
        println!("服务变更: {} -> {} 个实例", service_name, instances.len());
    }

    async fn on_instance_added(&self, service_name: &str, instance: &ServiceInstance) {
        println!("实例添加: {} -> {}:{}", service_name, instance.ip, instance.port);
    }

    async fn on_instance_removed(&self, service_name: &str, instance: &ServiceInstance) {
        println!("实例移除: {} -> {}:{}", service_name, instance.ip, instance.port);
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[tokio::test]
    async fn test_basic_usage() {
        let result = create_and_test_client().await;
        assert!(result.is_ok());
    }

    #[test]
    fn test_service_instance_creation() {
        let instance = ServiceInstance::new(
            "test".to_string(),
            "group".to_string(),
            "127.0.0.1".to_string(),
            8080,
        );
        
        assert_eq!(instance.service_name, "test");
        assert_eq!(instance.ip, "127.0.0.1");
        assert_eq!(instance.port, 8080);
    }
}